package com.sunfeng.gulimall.search.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author : 清风冷影
 * @Description:
 * @Date : 2021/11/15  21:22
 */
@Slf4j
public class ThreadTest2 {
    private static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // 任务1
        CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {
            log.info("任务1线程：" + Thread.currentThread().getId());
            int i = 10 / 4;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("任务1结束：");

            return i + "";
        }, executor);

        // 任务2
        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            log.info("任务2线程：" + Thread.currentThread().getId());
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("任务2结束");

            return "Hello";
        }, executor);
        // 任务1和任务2并行执行，只要有一个执行完成，就执行任务3，不使用任务1 或 任务2线程的结果，并且任务3没有返回值
        // future01.runAfterEitherAsync(future02, () -> log.info("任务三开始执行，没有之前的结果返回"));


        // 任务1和任务2并行执行，只要有一个执行完成，就执行任务3，使用任务1 或 任务2线程的结果，并且任务3没有返回值
        // 这里别使用自己定义的线程池 使用默认的 fork join pool
       // future01.acceptEitherAsync(future02, (o) -> log.info("任务三开始执行，返回的结果为：{}", o));

        // 任务1和任务2并行执行，只要有一个执行完成，就执行任务3，使用任务1 或 任务2线程的结果，并且任务3有返回值
        CompletableFuture<String> stringCompletableFuture = future01.applyToEitherAsync(future02, (res) -> {
            log.info("任务开始执行,之前任务执行的结果为,{}", res);
            return res + "孙峰";
        });
        System.out.println(stringCompletableFuture.get());

        executor.shutdown();
    }
}
